home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 25 / CU Amiga Magazine's Super CD-ROM 25 (1998)(EMAP Images)(GB)(Track 1 of 2)[!][issue 1998-08].iso / CUCD / Utilities / SmartFilesystem / Include / blockstructure.h < prev    next >
Encoding:
C/C++ Source or Header  |  1998-06-14  |  10.9 KB  |  338 lines

  1. #include "fs.h"
  2.  
  3. /* a BLCK is a block number.  Blocksize in bytes = SectorSize * SectorsPerBlock.
  4.  
  5.    BLCK pointers are used throughout the filesystem.  All structures which
  6.    require to associate themselves with another structure do so using BLCK
  7.    pointers.  Byte pointers are not used. */
  8.  
  9. typedef unsigned long BLCK;
  10. typedef BLCK BLCKn;
  11.  
  12. #define OBJECTCONTAINER_ID         MAKE_ID('O','B','J','C')
  13. #define HASHTABLE_ID               MAKE_ID('H','T','A','B')
  14. #define SOFTLINK_ID                MAKE_ID('S','L','N','K')
  15.  
  16. #define RESTOREINDEX_ID         MAKE_ID('R','S','T','I')
  17. #define TRANSACTIONSTORAGE_ID   MAKE_ID('T','R','S','T')
  18. #define TRANSACTIONFAILURE_ID   MAKE_ID('T','R','F','A')
  19. #define TRANSACTIONOK_ID        MAKE_ID('T','R','O','K')
  20.  
  21. /* a NODE is the number of a fsNode structure in a fsNodeContainer */
  22.  
  23. typedef unsigned long NODE;
  24.  
  25.  
  26.  
  27. /* Below is the standard block header.  This header is found before EVERY
  28.    type of block used in the filesystem, except data blocks.
  29.  
  30.    The id field is used to check if the block is of the correct type when
  31.    it is being referred to using a BLCK pointer.
  32.  
  33.    The checksum field is the SUM of all LONGs in a block plus one, and then
  34.    negated.  When applying a checksum the checksum field itself should be
  35.    set to zero.  The checking a checksum the checksum is okay if the result
  36.    of the checksum equals zero.
  37.  
  38.    The ownblock BLCK pointer points to the block itself.  This field is an
  39.    extra safety check to ensure we are using a valid block. */
  40.  
  41. struct fsBlockHeader {
  42.   ULONG id;         /* 4 character id string of this block */
  43.   ULONG checksum;   /* The checksum */
  44.   BLCK  ownblock;   /* The blocknumber of the block this block is stored at */
  45. };
  46.  
  47.  
  48.  
  49. /* Now follows the structure of the Boot block.  The Boot block is always
  50.    located at block offset 0.  It contains only a version number at the
  51.    moment to identify the block structure of the disk. */
  52.  
  53. struct fsBootBlock {
  54.   struct fsBlockHeader bheader;
  55.  
  56.   UWORD version;                   /* Version number of the filesystem block structure */
  57. };
  58.  
  59. #define STRUCTURE_VERSION (2)
  60.  
  61.  
  62.  
  63. /* The fsRootInfo structure has all kinds of information about the format
  64.    of the disk. */
  65.  
  66. struct fsRootInfo {
  67.   ULONG datecreated;
  68.  
  69.   BLCK  lastallocatedblock;        /* Block which was most recently allocated */
  70.   BLCK  lastallocatedadminspace;   /* AdminSpaceContainer which most recently was used to allocate a block */
  71.   NODE  lastallocatedextentnode;   /* ExtentNode which was most recently created */
  72.   NODE  lastallocatedobjectnode;   /* ObjectNode which was most recently created */
  73.  
  74.   BLCK  objectnodeindex;
  75.   BLCK  rovingpointer;
  76. };
  77.  
  78.  
  79.  
  80. /* An SFS disk has two Root blocks, one located at the start of
  81.    the partition and one at the end.  On startup the fs will check
  82.    both Roots to see if it is a valid SFS disk.  If either one is
  83.    missing SFS can still continue.
  84.  
  85.    A Root block could be missing on purpose.  For example, if you
  86.    extend the partition at the end (adding a few MB's) then SFS
  87.    can detect this with the information stored in the Root block
  88.    located at the beginning (since only the end-offset has changed).
  89.    Same goes for the other way around, as long as you don't change
  90.    start and end point at the same time.
  91.  
  92.    When a Root block is missing because the partition has been
  93.    made a bit larger, then SFS will in the future be able to
  94.    'resize' itself without re-formatting the disk. */
  95.  
  96. struct fsRootBlock {
  97.   struct fsBlockHeader bheader;
  98.  
  99.   UWORD version;              /* Version number of the filesystem block structure */
  100.   UWORD sequencenumber;       /* The Root with the highest sequencenumber is valid */
  101.  
  102.   ULONG datecreated;          /* Creation date (when first formatted).  Cannot be changed. */
  103.   UBYTE bits;                 /* various settings, see defines below. */
  104.   UBYTE pad1;
  105.   UWORD pad2;
  106.  
  107.   ULONG reserved1[2];
  108.  
  109.   ULONG firstbyteh;           /* The first byte of our partition from the start of the */
  110.   ULONG firstbyte;            /* disk.  firstbyteh = upper 32 bits, firstbyte = lower 32 bits. */
  111.  
  112.   ULONG lastbyteh;            /* The last byte of our partition, excluding this one. */
  113.   ULONG lastbyte;
  114.  
  115.   BLCK  totalblocks;          /* size of this partition in blocks */
  116.   ULONG blocksize;            /* blocksize used */
  117.  
  118.   ULONG reserved2[2];
  119.   ULONG reserved3[8];
  120.  
  121.   BLCK  bitmapbase;           /* location of the bitmap */
  122.   BLCK  adminspacecontainer;  /* location of first adminspace container */
  123.   BLCK  rootobjectcontainer;  /* location of the root objectcontainer */
  124.   BLCK  extentbnoderoot;      /* location of the root of the extentbnode B-tree */
  125.  
  126.   ULONG reserved4[4];
  127. };
  128.  
  129. #define ROOTBITS_CASESENSITIVE (128)   /* When set, filesystem names are treated case
  130.                                           insensitive (NOT IMPLEMENTED, RESERVED FOR FUTURE USE) */
  131.  
  132.  
  133. /* Below is the structure describing an Object.  Objects can be files or
  134.    directories.  Multiple Objects can be stored in an ObjectContainer
  135.    block.
  136.  
  137.    owneruid & ownergid:  These are not used at the moment.  They have
  138.    been reserved for future use.  They must be set to zero for now.
  139.  
  140.    objectnode:  This field contains a number uniquely identifying this
  141.    object.  This number can be used to find out the ObjectContainer
  142.    where the Object is stored in.  It is used to refer to an Object
  143.    without having to use BLCK pointers.
  144.  
  145.    protection:  Contains the Object's protection bits.  By default this
  146.    field is set to 0x0000000F, which means bits R, W, E and D are set
  147.    (note that this is opposite to what is used by AmigaDOS).
  148.  
  149.    data (files only):  Contains the BLCK number of the first data block of
  150.    a file.  To find out where the rest of the data is located this BLCK
  151.    number can be looked up in a special B+-Tree structure (see below).
  152.  
  153.    size (files only):  Contains the size of a file in bytes.
  154.  
  155.    hashtable (directories only):  A BLCK pointer.  It points to a
  156.    HashTable block.
  157.  
  158.    firstdirblock (directories only):  This BLCK pointer points to the 
  159.    first ObjectContainer block which belongs to this directory object.
  160.    For empty directories this field is zero.
  161.  
  162.    datemodified:  The date of the last modification of this Object.  The
  163.    date is stored in seconds from 1-1-1978 (enough for storing 136 years)
  164.  
  165.    bits:  See the defines below.  At the moment this field can be checked
  166.    to see if the object is a file or directory.  A bit is reserved for
  167.    links, but isn't currently used (and may or may not be used depending
  168.    on how and if links are implemented).
  169.  
  170.    name:  Directly following the main structure is the name of the object.
  171.    It is zero terminated.
  172.  
  173.    comment:  Directly following the name of the object is the comment
  174.    field.  This field is zero terminated as well (even if there is no
  175.    comment). */
  176.  
  177. struct fsObject {
  178.   UWORD owneruid;
  179.   UWORD ownergid;
  180.   NODE  objectnode;
  181.   ULONG protection;
  182.  
  183.   union {
  184.     struct {
  185.       BLCK  data;
  186.       ULONG size;
  187.     } file;
  188.  
  189.     struct {
  190.       BLCK  hashtable;   /* for directories & root */
  191.       BLCK  firstdirblock;
  192.     } dir;
  193.   } object;
  194.  
  195.   ULONG datemodified;
  196.   UBYTE bits;
  197.  
  198.   UBYTE name[0];
  199.   UBYTE comment[0];
  200. };
  201.  
  202. #define OTYPE_HARDLINK (32)
  203. #define OTYPE_LINK     (64)
  204. #define OTYPE_DIR      (128)
  205.  
  206. /* SFS supports Soft links.  When OTYPE_LINK is set and OTYPE_HARDLINK is
  207.    clear then the entry is a soft link.  The path of the soft link isn't
  208.    stored with the directory entry, but instead is stored as the file
  209.    data. */
  210.  
  211.  
  212.  
  213. /* The fsObjectContainer structure is used to hold various Objects which
  214.    have the same parent directory.  Objects always start at 2-byte
  215.    boundaries, which means sometimes a padding byte is inserted between
  216.    2 fsObject structures.
  217.  
  218.    parent:  The node-number of the parent Object.  The node number can be
  219.    used to lookup the BLCK number of the block where the parent Object is
  220.    located.
  221.  
  222.    next:  The next ObjectContainer belonging to this directory or zero if
  223.    it is the last in the chain.
  224.  
  225.    previous:  The previous ObjectContainer belonging to this directory or
  226.    zero if it is the first ObjectContainer.
  227.  
  228.    object:  A variable number of fsObject structures, depending on their
  229.    sizes and on the size of the block.  The next object structure can be
  230.    found by creating a pointer pointing to the name field of the current
  231.    object, then skip 2 strings (name & comment) and if the address is odd,
  232.    adding 1. */
  233.  
  234. struct fsObjectContainer {
  235.   struct fsBlockHeader bheader;
  236.  
  237.   NODE parent;
  238.   BLCK next;
  239.   BLCK previous;   /* 0 for the first block in the directory chain */
  240.  
  241.   struct fsObject object[0];
  242. };
  243.  
  244.  
  245.  
  246. /* fsHashTable is the structure of a HashTable block.  It functions much
  247.    like the HashTable found in FFS, except that it is stored in a seperate
  248.    block.  This block contains a number of hash-chains (about 120 for a
  249.    512 byte block).  Each hash-chain is a chain of Nodes.  Each Node
  250.    contains a BLCK pointer to an Object and the node number of the next
  251.    entry in the hash-chain.
  252.  
  253.    parent:  The node-number of the parent object.
  254.  
  255.    hashentry:  The node-number of the first entry of a specific
  256.    hash-chain. */
  257.  
  258. struct fsHashTable {
  259.   struct fsBlockHeader bheader;
  260.  
  261.   NODE parent;
  262.  
  263.   NODE hashentry[0];
  264. };
  265.  
  266.  
  267.  
  268. struct fsSoftLink {
  269.   struct fsBlockHeader bheader;
  270.  
  271.   NODE parent;
  272.   BLCK next;
  273.   BLCK previous;
  274.  
  275.   UBYTE string[0];
  276. };
  277.  
  278.  
  279.  
  280. struct fsBlockRestore {
  281.   BLCK from;   /* current location of block to restore */
  282.   BLCK to;     /* original location where the block should be restored to */
  283. };
  284.  
  285. /* Below is the structure of the special block which is used to restore
  286.    the disk in case of a write-failure which caused the filesystem to be
  287.    terminated during a write operation (ie, crash, powerloss, user reset).
  288.  
  289.    The block below is an index to other blocks which need to be restored
  290.    to certain positions on the disk to restore the disk to its original
  291.    state (before the fatal write operation started).
  292.  
  293.    How it works:
  294.  
  295.    The mere presence of this block on the disk indicates that a write
  296.    operation was interrupted.  If this block is present than it needs
  297.    to be checked and any changes which need to undone recorded in this
  298.    block need to be executed.  After succesfully undoing the changes
  299.    this block is simply wiped.  Write operations which terminate normally
  300.    will delete this block as soon as all changed have been made succesfully
  301.    so it will never be found on the disk unless a write operation was
  302.    interrupted. */
  303.  
  304. struct fsRestoreIndex {
  305.   struct fsBlockHeader bheader;
  306.  
  307.   struct fsBlockRestore blocks[0];
  308. };
  309.  
  310.  
  311. /* The blocks used for storing the Transaction buffer are linked in a
  312.    singly linked list.  The data they hold is a direct copy of all
  313.    Transaction data. */
  314.  
  315. struct fsTransactionStorage {
  316.   struct fsBlockHeader bheader;
  317.  
  318.   BLCK next;
  319.  
  320.   UBYTE data[0];
  321. };
  322.  
  323.  
  324. struct fsTransactionFailure {
  325.   struct fsBlockHeader bheader;
  326.  
  327.   BLCK firsttransaction;
  328. };
  329.  
  330.  
  331.  
  332. struct fsExtentBNode {
  333.   ULONG key;     /* data! */
  334.   ULONG next;
  335.   ULONG prev;
  336.   UWORD blocks;  /* The size in blocks of the region this Extent controls */
  337. };
  338.